#ifndef BT_API_H
#define BT_API_H

// The user should not modify this file, especially the stucture definition
// Beacuse these sturctue are already used in btstack.lib present by binary
//#include "UART.h"
#include "bt_uart_api.h"
//#include "sdkbt.h"

#if CONFIG_USE_BT_RLT8763BO == 1
typedef int (*sbc_send_cb_t)(void *data, uint8_t n_frames, uint16_t n_bytes);
typedef int (*sbc_play_cb_t)(void);
typedef int (*sbc_pause_cb_t)(void);
typedef void (*send_event_cb_t)(struct bt_task_event *event);

void appbt_a2dp_register_sbc_cb(sbc_send_cb_t send, sbc_play_cb_t play, sbc_pause_cb_t pause);
void appbt_a2dp_register_event_cb(send_event_cb_t send);
#endif

#define BT_UART_DMA_RX_DEBUG
#define FIRMWARE_POSITION_SD                0
#define FIRMWARE_POSITION_FLASH_PARTITION   1
#define FIRMWARE_POSITION_MEMORY            2

#define BT_HCI_MODE_H4                      0
#define BT_HCI_MODE_H5                      1

/* user configuration related define */
#define MAX_BT_NAME                 248
#define MAX_BT_PHONE_NUMBER         20
#define MAX_BT_DEVICE_RECORD        10

#define MAX_BT_OBEX_FILE_NAME       256
#define MAX_BT_OBEX_FILE_TYPE_SIZE  32
#define L2CAP_RETRANS_SUPPORT   1
#if L2CAP_RETRANS_SUPPORT
#define BT_OBEX_FRAME_SIZE          (8087 - MAX_BT_OBEX_FILE_TYPE_SIZE - MAX_BT_OBEX_FILE_NAME - 5)
#else
#define BT_OBEX_FRAME_SIZE          (4096 * 2)
#endif

#define BT_MODE_BR                  0
#define BT_MODE_BR_LE               1
#define BT_MODE_LE                  2

#define BT_ROLE_MASTER              0
#define BT_ROLE_SLAVE               1

#define BT_SNIFF_ON                 1
#define BT_SNIFF_OFF                0

#define BT_FIRMWARE_AT_SD           0
#define BT_FIRMWARE_AT_FLASH        1
#define BT_FIRMWARE_AT_MEMORY       2

#define BT_WAKELOCK_UART_TX_DMA     (1 << 0)
#define BT_WAKELOCK_UART_RECV       (1 << 1)
#define BT_WAKELOCK_UART_RX_DMA     (1 << 2)

typedef struct _ble_device_info_record{
	unsigned char valid;
	unsigned char address[6];
	unsigned char addr_type;
	unsigned short deviceState;
	unsigned char ltk[16];
	unsigned char keyType;
	unsigned short ediv;
	unsigned char rand[8];
    unsigned char enc_size;
	unsigned char csrk[16];
	unsigned char peer_csrk[16];
	unsigned char signCounter;
	unsigned char irk[16];
	unsigned char peer_irk[16];
}__attribute__((packed)) ble_device_info_record;

#define MAX_BLE_DEVICE_RECORD		10
#define BLE_RECORD_FILE  			"BLEDev"
#define LE_HIDS                     1

struct bt_addr {
    unsigned char bytes[6];
};

struct bt_device_record {
    char name[MAX_BT_NAME];
    unsigned int cod;
    unsigned char addr[6];
    unsigned char linkkey[16];
    int linkkey_type;
    int hfp_volume;
    int a2dp_volume;
    struct bt_device_record *next;
};

struct bt_hardware_cfg {
    int baudrate; // 115200, 921600, 3000000
#ifndef UART_NEW_VERSION
    bt_uart_cfg *uart_cfg;
#else
	uartdrv_cfg *uart_cfg;
#endif
    int reset_pin; // -1: not reset BT chip through reset PIN
    int pwdn_pin; // -1: no PWDN pin -- BT_LDO_EN
    int bt_wakeup_host_pin; // -1: not use wakeup PIN
    int host_wakeup_bt_pin; // -1: not use wakeup PIN
    unsigned int clock32;
};

struct bt_br_common_cfg {
    char name[MAX_BT_NAME];
    unsigned char addr[6];
    unsigned char discoverable; // 0: cannot be searched by other device; 1: can be searched
    unsigned char connectable; // 0: non-connectable; 1: connectable
    unsigned int cod;
    unsigned char io_capability; // 0: DisplayOnly; 1: DisplayYesNo; 2: KeyboardOnly; 3: NoInputNoOutput
    unsigned short int inquiry_scan_interval;
    unsigned short int inquiry_scan_window;
};

struct bt_le_common_cfg {
    unsigned char random_address[6];
    unsigned char smp_io_capability; // 0: DisplayOnly; 1: DisplayYesNo; 2: KeyboardOnly; 3: NoInputNoOutput
    unsigned char smp_secure_connection;
};

struct bt_profile_cfg {
    int hfp; // 0: not have HFP; 1: have HFP profile
    int a2dp; // 0: not have A2DP; 1: have A2DP profile
    int avrcp; // 0: not have AVRCP; 1: have AVRCP profile
    int spp; // 0: not have SPP; 1: have SPP profile
    int obex; // 0: not have OBEX; 1: have OBEX profile
    int pbap; // 0: not have PBAP; 1: have phone book profile
};

struct bt_user_cfg {
    struct bt_hardware_cfg hw;
    struct bt_br_common_cfg br_common;
    struct bt_le_common_cfg le_common;
    struct bt_profile_cfg profile;
    struct bt_device_record *record;
    int firmware_where; // 0: SD; 1: flash; 2: memory
    unsigned char *bt_firmware;
    int bt_firmware_size;
    unsigned char *bt_nvm_lst;
    int bt_nvm_lst_size;
    int h4_h5; // 0: h4; 1: h5.
    int bt_mode; // 0: br only; 1: br + le; 2: le only
    int bt_chip_id; // 5801, 5803
    int xip;
	ble_device_info_record *ble_rec;
};

struct bt_user_init_cfg {
    char name[MAX_BT_NAME];
    unsigned char discover_connect_able;
    int bt_wakeup_host_pin;
    unsigned char *bt_firmware;
    int bt_firmware_size;
    unsigned char *bt_nvm_lst;
    int bt_nvm_lst_size;
    int firmware_where;
};

/* command and event related define */
struct bt_task_command {
    int command_id;
    void (*execute_cb)(void *arg);
    int payload_length;
    void *payload;
};

struct bt_task_inquiry {
    unsigned char inquiry_length;
    unsigned char num_responses;
};

struct bt_task_bonding_accept {
    unsigned char addr[6];
    int accept;
};

struct bt_task_pin_reply {
    struct bt_addr addr;
    char pin[64];
};

struct bt_task_pin_negative_reply {
    struct bt_addr addr;
};

struct bt_task_user_passkey_request_reply {
    struct bt_addr addr;
    uint32_t numeric_value; /*valid values are decimal 000000 to 999999*/
};

struct bt_task_user_passkey_request_negative_reply {
    struct bt_addr addr;
};

struct bt_task_send_keypress_notification {
    struct bt_addr addr;
    unsigned char notification_type;
};

struct bt_task_a2dp_media_data {
    unsigned int length;
    unsigned char *data;
    unsigned int timestamp;
    unsigned int seq_num;
    unsigned char payload_type;
    unsigned char frames;
};

struct bt_task_hfp_connect {
    unsigned char addr[6];
    int call_status;
};

struct bt_task_hfp_call_status {
    int ciev_index;
    int value;
    int delay;
};

struct bt_task_hfp_update_phone_number {
    char number[MAX_BT_PHONE_NUMBER];
    char type[MAX_BT_PHONE_NUMBER];
};

struct bt_task_obex_file_send {
    unsigned int total;
    unsigned char *data;
    unsigned int payload_size;
    char type[MAX_BT_OBEX_FILE_TYPE_SIZE];
    char name[MAX_BT_OBEX_FILE_NAME]; // name: unicode type, should be uint16
    unsigned int name_size;
    int final;
    int tid;
};

struct bt_task_obex_send_response {
    int tid;
    unsigned char response_code;
};

struct bt_task_le_adv_parameters {
    unsigned short int interval_min;
    unsigned short int interval_max;
    unsigned char advertising_type; // LE_ADV_TYPE_XXX
    unsigned char own_address_type;
    unsigned char peer_address_type;
    struct bt_addr peer_address;
    unsigned char filter; /* 0x00: process scan and connection request from all devices
                             0x01: process connection request from all devices
                                   and scan request only from White List
                             0x02: process scan request from all devices
                                   and conneciton request only from White List
                             0x03: process scan and connection reques only from in the White List
                          */
};

struct bt_task_le_white_list {
    struct bt_addr addr;
    unsigned char type;
};

struct bt_task_le_ext_adv_parameters {
    unsigned char handle;
    unsigned short int properties;
    unsigned int interval_min;
    unsigned int interval_max;
    unsigned char channel;
    unsigned char own_address_type;
    unsigned char peer_address_type;
    struct bt_addr peer_address;
    unsigned char filter_policy;
    unsigned char tx_power;
    unsigned char primary_phy;
    unsigned char secondary_adv_max_skip;
    unsigned char secondary_phy;
    unsigned char sid;
    unsigned char scan_request_notification;
};

struct bt_task_le_ext_adv_enable {
    unsigned char enable;
    unsigned char number;
    unsigned char *handle;
    unsigned short *duration;
    unsigned char *max_event;
};

struct bt_task_le_set_adv_random_address {
    unsigned char handle;
    struct bt_addr addr;
};

struct bt_task_le_set_random_address {
    struct bt_addr addr;
};

struct bt_task_le_adv_data {
    unsigned char data[31];
    unsigned char length;
};

struct bt_task_le_ext_adv_data {
    unsigned char data[251];
    unsigned char length;
    unsigned char handle;
    unsigned char operation;
    unsigned char fragment;
};

struct bt_task_le_scan {
    unsigned char type;
    unsigned short int interval;
    unsigned short int window;
    unsigned char own_address_type;
};

struct bt_task_le_register_service {
    void *service;
    int count;
};

struct bt_task_le_update_attribute {
    void *attribute;
};

struct bt_task_le_notify_indicate {
    unsigned short acl;
    unsigned short att;
    unsigned char *data;
    int size;
};

struct bt_task_le_connect {
    struct bt_addr addr;
    int type;
};

struct bt_task_le_read_by_group_type_request {
    unsigned short starting;
    unsigned short ending;
    unsigned short uuid;
};

struct bt_task_le_read_by_type_request {
    unsigned short starting;
    unsigned short ending;
    unsigned short uuid;
};

struct bt_task_le_find_information_request {
    unsigned short starting;
    unsigned short ending;
};

struct bt_task_le_write {
    unsigned short att_handle;
    unsigned char *data;
    unsigned short length;
};

struct bt_task_le_read {
    unsigned short att_handle;
};

struct bt_task_test_le_enhanced_receiver {
    unsigned char channel;
    unsigned char PHY;
    unsigned char modulation_index;
};

struct bt_task_test_le_enhanced_transmitter {
    unsigned char channel;
    unsigned char length_of_test_data;
    unsigned char packet_payload;
    unsigned char PHY;
};

struct bt_task_test_tx_tone {
    unsigned char start_stop;
    unsigned char channel;
    unsigned char power;
    unsigned char type;
};

struct bt_task_test_tx_packet {
    unsigned char start_stop;
    unsigned char channel;
    unsigned char power;
    unsigned char modulation;
    unsigned char dh_type;
    unsigned char data_pattern;
    struct bt_addr addr;
};

struct bt_task_test_rx_packet {
    unsigned char start_stop;
    unsigned char channel;
    unsigned char packet_type;
    unsigned char data_pattern;
    struct bt_addr addr;
};

#define MAX_BT_VENDOR_CMD_PARAMETERS 16
struct bt_task_vendor_cmd {
    unsigned int cmd;
    unsigned int parameters[MAX_BT_VENDOR_CMD_PARAMETERS];
    unsigned char valid_parametes;
};

struct bt_task_le_smp_start {
    struct bt_addr addr;
};

struct bt_task_spp_send_data {
    u_int16 length;
    u_int8* data;
    u_int16 spp_port;
};

//for btstack
enum{
    BTBS_CALL_STATE_IDLE,
    BTBS_CALL_STATE_DIALING,
    BTBS_CALL_STATE_INCONING,
    BTBS_CALL_STATE_ALERTING,
    BTBS_CALL_STATE_WAITING,
    BTBS_CALL_STATE_HELD, //5
    BTBS_CALL_STATE_OUTGOING_CALL_ESTABLISHED,
    BTBS_CALL_STATE_AG_ANSWER_INCOMING_CALL,
    BTBS_CALL_STATE_AG_JOIN_HELD_CALL,

    BTBS_CALL_STATE_OUTGOING_CALL_REJECTED,
    BTBS_CALL_STATE_TERMINATE_CALL,    //10
    BTBS_CALL_STATE_DROP,
};

//for btstack
struct bt_task_hfp_bs_call_status_update {
    int call_status;
    int call_dir;
    int call_id;
};

struct bt_task_le_passkey {
    unsigned char set_enable; // 0: disable 1: enable
    unsigned int passkey;
    void *callback;
};

enum {
    BTTASK_CMD_ACL_CONNECT = 0,
    BTTASK_CMD_ACL_DISCONNECT,
    BTTASK_CMD_INQUIRY,
    BTTASK_CMD_INQUIRY_CANCEL,
    BTTASK_CMD_SET_VISIBLE,
    BTTASK_CMD_SET_VISIBLE_CONNECTABLE,
    BTTASK_CMD_SET_LOCAL_NAME,
    BTTASK_CMD_BONDING_ACCEPT,
    BTTASK_CMD_BONDING,
    BTTASK_CMD_UNBONDING,
    BTTASK_CMD_PIN_REPLY, // 10
    BTTASK_CMD_PIN_NEGATIVE_REPLY,
    BTTASK_CMD_USER_PASSKEY_REQUEST_REPLY,
    BTTASK_CMD_USER_PASSKEY_REQUEST_NEGATIVE_REPLY,
    BTTASK_CMD_SEND_KEYPRESS_NOTIFICATION,
    BTTASK_CMD_CONNECT_A2DP,
    BTTASK_CMD_DISCONNECT_A2DP,
    BTTASK_CMD_A2DP_SEND_START,
    BTTASK_CMD_A2DP_SEND_SUSPEND,
    BTTASK_CMD_A2DP_SEND_MEDIA_DATA,
    BTTASK_CMD_CONNECT_AVRCP, // 20
    BTTASK_CMD_DISCONNECT_AVRCP,
    BTTASK_CMD_CONNECT_HFP,
    BTTASK_CMD_DISCONNECT_HFP,
    BTTASK_CMD_HFP_ACCEPT_CONNECTION,
    BTTASK_CMD_HFP_REJECT_CONNECTION,
    BTTASK_CMD_HFP_UPDATE_CALLSTATUS,
    BTTASK_CMD_HFP_UPDATE_PHONE_NUMBER,
    BTTASK_CMD_HFP_UPDATE_CALLHOLD,
    BTTASK_CMD_HFP_SET_SPEAKER_GAIN,
    BTTASK_CMD_HFP_SET_MICROPHONE_GAIN, //30
    BTTASK_CMD_HFP_SEND_AT_RAWDATA,
    BTTASK_CMD_CONNECT_OBEX_OPP,
    BTTASK_CMD_DISCONNECT_OBEX_OPP,
    BTTASK_CMD_OBEX_OPP_SEND_FILE_START,
    BTTASK_CMD_OBEX_OPP_SEND_FILE,
    BTTASK_CMD_OBEX_RESPONSE,
    BTTASK_CMD_CONNECT_SPP,
    BTTASK_CMD_SETUP_SCO,
    BTTASK_CMD_DISCONNECT_SCO,
    BTTASK_CMD_SPP_CONNECT, //40
    BTTASK_CMD_SPP_DISCONNECT,
    BTTASK_CMD_SPP_SEND_DATA,

    //for btstack
    BTTASK_CMD_HFP_BS_CALL_STATUS_UPDATE,

    BTTASK_CMD_LE_SET_RANDOM_ADDRESS = 70,
    BTTASK_CMD_LE_SET_ADV_PARAMETERS,
    BTTASK_CMD_LE_SET_ADV_DATA,
    BTTASK_CMD_LE_SET_ADV_ENABLE,
    BTTASK_CMD_LE_SCAN,
    BTTASK_CMD_LE_SCAN_STOP,
    BTTASK_CMD_LE_SET_SCAN_RESPONSE,
    BTTASK_CMD_LE_REGISTER_SERVICE,
    BTTASK_CMD_LE_UNREGISTER_SERVICE,
    BTTASK_CMD_LE_UPDATE_ATTRIBUTE,
    BTTASK_CMD_LE_NOTIFY,
    BTTASK_CMD_LE_INDICATE,
    BTTASK_CMD_LE_CONNECT,
    BTTASK_CMD_LE_DISCONNECT,
    BTTASK_CMD_LE_MTU_REQUEST,
    BTTASK_CMD_LE_CLIENT_READ_BY_TYPE_REQUEST,
    BTTASK_CMD_LE_CLIENT_READ_REQUEST,
    BTTASK_CMD_LE_CLIENT_READ_BLOB_REQUEST,
    BTTASK_CMD_LE_CLIENT_READ_MULTIPLE_REQUEST,
    BTTASK_CMD_LE_CLIENT_READ_BY_GROUP_TYPE_REQUEST,
    BTTASK_CMD_LE_FIND_INFO_REQUEST,
    BTTASK_CMD_LE_FIND_BY_TYPE_VALUE_REQUEST,
    BTTASK_CMD_LE_WRITE_REQUEST,
    BTTASK_CMD_LE_WRITE_COMMAND,
    BTTASK_CMD_LE_SIGNED_WRITE_COMMAND,
    BTTASK_CMD_TEST_DUT,
    BTTASK_CMD_TEST_TX_TONE,
    BTTASK_CMD_TEST_TX_PACKET,
    BTTASK_CMD_TEST_RX_PACKET,
    BTTASK_CMD_TEST_LE_ENHANCED_RECEIVER,
    BTTASK_CMD_TEST_LE_ENHANCED_TRANSMITTER,
    BTTASK_CMD_TEST_LE_END,
    BTTASK_CMD_LE_SET_ADV_SET_RANDOM_ADDRESS,
    BTTASK_CMD_LE_SET_EXT_ADV_PARAMETERS,
    BTTASK_CMD_LE_SET_EXT_ADV_DATA,
    BTTASK_CMD_LE_SET_EXT_SCAN_RESPONSE,
    BTTASK_CMD_LE_SET_EXT_ADV_ENABLE,
    BTTASK_CMD_LE_CLEAR_WHITE_LIST,
    BTTASK_CMD_LE_SET_WHITE_LIST,
    BTTASK_CMD_LE_SMP_SECURITY_REQUEST,
    BTTASK_CMD_LE_READ_ADV_PHY_TXPOWER,
    BTTASK_CMD_RAW_VENDOR_CMD,
    BTTASK_CMD_TEST_READ_RSSI,
    BTTASK_CMD_TEST_HCI_RESET,
    BTTASK_CMD_TEST_SET_COEXIST_MODE,
    BTTASK_CMD_LE_CLEAN_PAIR_INFO,
    BTTASK_CMD_LE_DUMP_PAIR_INFO,
    BTTASK_CMD_LE_RELOAD_PAIR_INFO,
    BTTASK_CMD_LE_SET_PASSKEY_FROM_LOCAL,
    BTTASK_CMD_LE_SET_PAIR_ENABLE, // enable normal pair rsp

    // New command for custom
    BTTASK_CMD_SET_CHECK_CONTROLLER_ALIVE = 256,

};

struct bt_task_event {
    unsigned short int event_type;
    unsigned short int event_id;
    int payload_length;
    void *payload;
};

typedef void (*bt_event_handle_t)(struct bt_task_event *event);

enum {
    BTTASK_IND_TYPE_COMMON,
    BTTASK_IND_TYPE_ACL,
    BTTASK_IND_TYPE_SCO,
    BTTASK_IND_TYPE_A2DP,
    BTTASK_IND_TYPE_AVRCP,
    BTTASK_IND_TYPE_HFP,
    BTTASK_IND_TYPE_OBEX,
    BTTASK_IND_TYPE_SPP,
    BTTASK_IND_TYPE_LE
};

enum {
    BTTASK_IND_INQUIRY_RESULT,
    BTTASK_IND_INQUIRY_COMPLETE,
    BTTASK_IND_PAIRING_REQUEST,
    BTTASK_IND_PAIRED,
    BTTASK_IND_PIN_REQUEST,
    BTTASK_IND_USER_PASSKEY_NOTIFICATION,
    BTTASK_IND_USER_PASSKEY_REQUEST,
    BTTASK_IND_POWERUP_COMPLETE,
    BTTASK_IND_POWERUP_FAILED,
    BTTASK_IND_SHUTDOWN_COMPLETE,
    BTTASK_IND_BTFIRMWARE_ASSERT,
    BTTASK_IND_HCI_COMPLETE_EVENT,
    BTTASK_IND_NULL, // message was eaten by upper layer
    BTTASK_IND_NAME,
    BTTASK_IND_RSSI,
    BTTASK_IND_SLAVE_LE_BOND_COMPLETE, //slave role, bond
    BTTASK_IND_HEADSET_CONNECTED,
}; // common define

enum {
    BTTASK_IND_ACL_CONNECTED,
    BTTASK_IND_ACL_DISCONNECTED,
    BTTASK_IND_ACL_CONNECT_FAILED,
}; // ACL define

enum {
    BTTASK_IND_SCO_CONNECTED,
    BTTASK_IND_SCO_DISCONNECTED,
    BTTASK_IND_SCO_CONNECT_FAILED,
}; // SCO define

enum {
    BTTASK_IND_A2DP_CONNECTED,
    BTTASK_IND_A2DP_MEIDA_CONNECTED,
    BTTASK_IND_A2DP_DISCONNECTED,
    BTTASK_IND_A2DP_START,
    BTTASK_IND_A2DP_MEDIA_SEND_COMPLETE,
    BTTASK_IND_REMOTE_SBC_CAPABILITIES,
    BTTASK_IND_A2DP_START_PRIVATE,
    BTTASK_IND_A2DP_MEDIA_MTU,
}; // a2dp define

enum {
    BTTASK_IND_AVRCP_CONNECTED,
    BTTASK_IND_AVRCP_DISCONNECTED,
    BTTASK_IND_AVRCP_KEY_PRESSED,
    BTTASK_IND_AVRCP_KEY_RELEASED,
}; // avrcp define

enum {
    BTTASK_IND_HFP_CONNECTION_REQUEST, // HF initate a connection to AG
    BTTASK_IND_HFP_CONNECTED, // connection complete, HF or AG initate this connection
    BTTASK_IND_HFP_DISCONNECTED,
    BTTASK_IND_HFP_ATA,
    BTTASK_IND_HFP_ATCHUP,
    BTTASK_IND_HFP_DIAL,
    BTTASK_IND_HFP_ATCHLD,
    BTTASK_IND_HFP_VOICE_RECOGNITION,
    BTTASK_IND_HFP_SPEAKER_VOLUME,
    BTTASK_IND_HFP_MICROPHONE_GAIN,
    BTTASK_IND_HFP_SDP_FAILED, // remote device not support HFP
}; // hfp define

enum {
    BTTASK_IND_OBEX_OPP_SERVER_CONNECTED,
    BTTASK_IND_OBEX_OPP_SERVER_DISCONNECTED,
    BTTASK_IND_OBEX_OPP_SERVER_OBJECT_FILE_INFO,
    BTTASK_IND_OBEX_OPP_SERVER_OBJECT_RECIEVE_DATA,
    BTTASK_IND_OBEX_OPP_SERVER_OBJECT_RECIEVE_FINISH,
    BTTASK_IND_OBEX_OPP_SERVER_OBJECT_RECIEVE_ABORT,
    BTTASK_IND_OBEX_OPP_CLIENT_CONNECTED,
    BTTASK_IND_OBEX_OPP_CLIENT_DISCONNECTED,
    BTTASK_IND_OBEX_OPP_CLIENT_OBJECT_PUT_FAILED,
    BTTASK_IND_OBEX_OPP_CLIENT_OBJECT_PUT_SUCCESS,
    BTTASK_IND_OBEX_OPP_CLIENT_OBJECT_PUT_CONTINUE,
    BTTASK_IND_OBEX_PBAP_SERVER_CONNECTED,
}; // obex define

enum {
    BTTASK_IND_SPP_CONNECT_IND,
    BTTASK_IND_SPP_CONNECT_CNF,
    BTTASK_IND_SPP_DISCONNECT_IND,
    BTTASK_IND_SPP_DISCONNECT_CNF,
    BTTASK_IND_SPP_DATA_IND,
    BTTASK_IND_SPP_DATA_CNF,
    BTTASK_IND_SPP_FLOW_IND,
 }; // SPP define

enum {
    BTTASK_IND_LE_SCAN_EVENT,
    BTTASK_IND_LE_GATT_CONNECTED,
    BTTASK_IND_LE_GATT_DISCONNECTED,
    BTTASK_IND_LE_HANDLE_VALUE_CFM, // indicate confirm response
    BTTASK_IND_LE_ERROR_RESPONSE,
    BTTASK_IND_LE_MTU_EXCHANGED, // this indication means MTU be changed (no matter master or slave)
    BTTASK_IND_LE_CLIENT_MTU_EXCHANGED, // if MTU exchang finished, GATT client can do next action
    BTTASK_IND_LE_CLIENT_READ_BY_GROUP_TYPE_RSP,
    BTTASK_IND_LE_CLIENT_READ_BY_TYPE_RSP,
    BTTASK_IND_LE_CLIENT_FIND_INFOMATION_RSP,
    BTTASK_IND_LE_CLIENT_READ_RSP,
    BTTASK_IND_LE_CLIENT_READ_BLOB_RSP,
    BTTASK_IND_LE_CLIENT_HANDLE_NOTIFY,
    BTTASK_IND_LE_CLIENT_HANDLE_INDIATION,
    BTTASK_IND_LE_WHITE_LIST_SIZE,
    BTTASK_IND_SMP_PASSKEY,
    BTTASK_IND_ADV_PHY_TXPOWER,
    BTTASK_IND_LE_CLIENT_WRITE_RSP,	//indicate get write resp
}; // le define

struct bt_event_inquiry {
    char name[MAX_BT_NAME];
    int length;
    unsigned int cod;
    unsigned char addr[6];
    char rssi;
};

struct bt_event_pairing_request {
    unsigned char name[MAX_BT_NAME];
    struct bt_addr addr;
    unsigned int numeric_value;
    unsigned int cod;
    unsigned char io_capability;
};

struct bt_event_paired {
    unsigned char name[MAX_BT_NAME];
    unsigned char addr[6];
    unsigned linkey[16];
    int linkkey_type;
    unsigned int cod;
};

struct bt_event_pin_request {
    struct bt_addr addr;
    unsigned char name[MAX_BT_NAME];
    unsigned int cod;
};

struct bt_event_user_passkey_notification {
    struct bt_addr addr;
    unsigned int passkey;
};

struct bt_event_user_passkey_request {
    struct bt_addr addr;
};

struct bt_event_name_indication {
    struct bt_addr addr;
    unsigned char name[MAX_BT_NAME];
    int name_length;
};

struct bt_event_acl_connect {
    unsigned char addr[6];
    unsigned short int handle;
};

struct bt_event_acl_disconnect {
    unsigned short int reason;
    unsigned short int handle;
};

struct bt_event_le_bond_complete {
    unsigned char address_type;
    struct bt_addr address;
};

struct bt_event_sco {
    unsigned char addr[6];
    unsigned int handle;
    unsigned int role;
};

struct bt_event_a2dp_connect {
    int cid;
    unsigned char addr[6];
};

struct bt_event_a2dp_disconnect {
    int cid;
};

struct bt_event_a2dp_media_mtu {
    int cid;
    unsigned int mtu;
};


struct bt_event_sbc_capabilities {
    unsigned int remote_device_samples_support;
    unsigned int config_samples;
    unsigned int config_sbc_bitpool;
    unsigned int config_channel_mode;
    unsigned int config_allocation;
    unsigned int config_subbands;
    unsigned int config_blocks;
};

struct bt_event_avrcp_connect {
    unsigned char addr[6];
};

struct bt_event_hfp_connect {
    unsigned char addr[6];
};

struct bt_event_hfp_dial {
    int type; // 0: number; 1: redial; 2: memory
    unsigned char number[MAX_BT_PHONE_NUMBER];
    int length;
};

struct bt_event_obex_file_info {
    char file_name[MAX_BT_OBEX_FILE_NAME];
    int file_name_size;
    char file_type[MAX_BT_OBEX_FILE_TYPE_SIZE]; // UTF-8 not need size
    int file_size;
};

struct bt_event_obex_receive_finish {
    //file_info
    struct bt_event_obex_file_info file_info;

    //data info
    int data_len;
    void* data;
};

struct bt_event_spp_event {
    unsigned char addr[6];
    u_int8 port;
    u_int8 result;
    u_int16 max_frame_size;
    u_int16 data_len;
    u_int8* data;
};

struct bt_event_le_scan_event {
    unsigned char event_type;
    unsigned char address_type;
    struct bt_addr address;
    unsigned char length;
    unsigned char data[31];
    char rssi;
};

struct bt_event_le_att_connected {
    struct bt_addr addr;
    unsigned char addr_type;
    int acl_handle;
    int role;
    unsigned char peer_irk[16];
};

struct bt_event_le_error_rsp {
    unsigned char request;
    unsigned short att_handle;
    unsigned char code;
};

struct bt_event_le_mtu_exchange {
    int mut;
    int acl_handle;
};

struct bt_event_le_read_by_group_type_rsp {
    unsigned char size;
    unsigned char value[255];
};

struct bt_event_le_read_by_type_rsp {
    unsigned char size;
    unsigned char value[255];
};

struct bt_event_le_read_rsp {
    unsigned char size;
    unsigned char value[255];
};

struct bt_event_le_client_handle_notify {
    unsigned short acl_handle;
    unsigned short handle;
    unsigned char value[255];
    int size;
};

struct bt_event_le_client_handle_indication {
    unsigned short acl_handle;
    unsigned short handle;
    unsigned char value[255];
    int size;
};

struct bt_event_le_common_rsp {
    unsigned char size;
    unsigned char value[255];
};

struct bt_event_le_smp_passkey {
    struct bt_addr addr;
    unsigned int passkey_value;
};

struct bt_event_le_adv_phy_txpower {
    unsigned char power_level;
};

struct bt_event_hci_command_complete {
    unsigned short opcode;
    unsigned int status;
    unsigned char data[255];
};

typedef void (*bt_stack_shutdown_clearup)(void);

struct bt_event_shutdown_complete {
    bt_stack_shutdown_clearup clearup;
};

#define BT_ERR_CODE_UNKNOWN_CONNECTION_IDENTIFIER           0x02
#define BT_ERR_CODE_HARDWARE_FAILURE                        0x03
#define BT_ERR_CODE_PAGE_TIMEOUT                            0x04
#define BT_ERR_CODE_AUTHENTICATION_FAILURE                  0x05
#define BT_ERR_CODE_PIN_or_KEY_MISSING                      0x06
#define BT_ERR_CODE_CONNECTION_TIMEOUT                      0x08
#define BT_ERR_CODE_CONNECTION_ALREADY_EXISTS               0x0B
#define BT_ERR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED      0x10
#define BT_ERR_CODE_REMOTE_USER_TERMINATED_CONNECTION       0x13
#define BT_ERR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST     0x16
// private error code
#define BT_ERR_CODE_OBEX_SEND_FAILED_BAD_STATUS             0x70
#define BT_ERR_CODE_OBEX_SEND_FAILED_FILE_NAME_TOO_LONG     0x71


#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/* function declare */

// API: config BT chip default baudrate
// should be execute before appbt_open
int appbt_config_btchip(unsigned int id);

// API: config UART baudrate
// should be execute before appbt_open
int appbt_config_bt_uart(unsigned int baudrate);
// API: config BT GPIO
// config which pin used in this project
// should be execute before appbt_open
int appbt_config_bt_gpio(int reset_pin, int pdn_pin,
int host_wakeup_bt_pin, int bt_wakeup_host_pin);
// API: config BT mode
// BT_MODE_BR or BT_MODE_LE or BT_MODE_BR_LE
// should be execute before appbt_open
int appbt_config_bt_mode(int mode);
// API: config BT firmware store where
// should be execute before appbt_open
// bt_firmware: build_ram_only.bin also name as btbin.bin
// bt_nvm_lst: bt_update.lst also name as btlst.bin
int appbt_config_firmware(int firmware_where,
                          unsigned char *bt_firmware, int bt_firmware_size,
                          unsigned char *bt_nvm_lst, int bt_nvm_lst_size);
// API: config BT HCI mode
// should be execute before appbt_open
// mode: BT_HCI_MODE_H4 or BT_HCI_MODE_H5
int appbt_config_hci_mode(int mode);
// API: quiry which HCI mode is used
int appbt_config_get_hci_mode(void);
// API: BT power on request
// Parameters: if user want handle BT event by self, set this callback
//             if user want use default BT event handle, set this NULL
int appbt_open(bt_event_handle_t handle, struct bt_user_init_cfg *init);
// API: BT power off request
int appbt_close(void);
// API: setup ACL connection request to target device
int appbt_acl_connect(struct bt_addr addr);
// API: disconnect a ACL connection
int appbt_acl_disconnect(uint16 handle);
// API: HCI Reset request
int appbt_test_hci_reset(void);
// API: Read RSSI request
int appbt_test_read_rssi(uint16 handle);
// API: Set Coexist mode
int appbt_set_coexist_mode(uint16 coexist);
// API: make a pair to target device
// this API bonding device only, after bonding complete, will disconnect ACL automaticly
int appbt_bonding(struct bt_addr addr);
// API: accept bonding request
int appbt_accept_bonding(struct bt_addr addr, int accept_reject);
// API: unbond device. this API should be executed at disconnect status
// user can also disconnect and unbond device through appbt_disconnect_phone/appbt_disconnect_headset
// if user unbond device through appbt_disconnect_headset/appbt_disconnect_phone should fill in the address parameters
int appbt_unbond(struct bt_addr addr);
// API: reply PIN code to target device
int appbt_pin_reply(struct bt_addr addr, char *pin);
// API: negative reply PIN to target device
int appbt_pin_negative_reply(struct bt_addr addr);
// API: user passkey request reply to target device
int appbt_user_passkey_request_reply(struct bt_addr addr, uint32_t numeric_value);
// API: user passkey request negative reply to target device
int appbt_user_passkey_request_negative_reply(struct bt_addr addr);
// API: keypress notification to target device
int appbt_send_keypress_notification(struct bt_addr addr, unsigned char notification_type);

// API: search other device
//      search result will report through BTTASK_IND_INQUIRY_RESULT
// inquiry_length: range: 0x01~0x30
//                 time = N * 1.28s
// num_responses: 0x00 unlimited number of responses
//                0x01~0xff
int appbt_inquiry(unsigned char inquiry_length, unsigned char num_responses);
// API: cancel inquiry
int appbt_inquiry_cancel(void);
// API: set bluetooth visiable and connectable
// Parameters: 0 - not visiable
//             1 - visiable
int appbt_set_visiable(int visiable);
// API: set bluetooth visiable and connectable
// Parameters: 0 - not visiable and connectable
//             1 - visiable and connectable
int appbt_set_visisable_connectable(int enable);
// API: change bluetooth local name
int appbt_change_local_name(const char *name);

// API: stack report BT event through this API
//      user should implement this API(bt_event_handle_t), or use default
// Parameters: BT event. Memory allocated through bt_malloc(), this function should free memory if not use default code
int send_bt_event(struct bt_task_event *event);
// API: set some message to stack. generally used internally
int set_bttask_flag(unsigned int flag);

// system will call this API, if system enter sleep. user can ignore this
void appbt_bt_enter_sleep(void);
// system will call this API, if system exit sleep. user can ignore this
void appbt_bt_exit_sleep(void);

// API: test mode
int appbt_bt_dut(void);
// API: le clear device record
void appbt_le_clear_device_record(void);
// API: LE recv test mode
int appbt_test_le_enhanced_receiver
    (unsigned char channel, unsigned char PHY, unsigned char modulation_index);
// API: LE send test mode
int appbt_test_le_enhanced_transmiter
    (unsigned char channel, unsigned char length_of_test_data,
     unsigned char packet_payload, unsigned char PHY);
// API: LE test mode end
int appbt_test_le_end(void);
// API: BR test mode -- send tone
// start_stop: 0 - stop send; 1 - start send
// channel: BT channel. valid value 0-78
//          0: 2402 MHz
//          1: 2402 + 1 MHz
//          n: 2402 + n MHz
// power: RF power. valid value 0-4. each grade difference is 4db
// type: tone type. valid value 0-6
//       0: 100KHz
//       1: 250KHz
//       2: 500KHz
//       3: 800KHz
//       4: 1000KHz
//       5: 1300KHz
//       6: 2000KHz
int appbt_bt_test_txtone(unsigned char start_stop,
    unsigned char channel, unsigned char power, unsigned char type);
// API: BR test mode -- send packet
// start_stop: 0 - stop send; 1 - start send
// channel: BT channel. valid value 0-78
//          0: 2402 MHz
//          1: 2402 + 1 MHz
//          n: 2402 + n MHz
// modulation: 1 - BR@1M; 2 - EDR@2M; 3 - EDR@3M
// dh_type: 1 - xDH1; 3 - xDH3; 5 - xDH5
// data_pattern: 1: 0 pattern
//               2: 1 pattern
//               3: 1010 pattern
//               4: pseudorandom bit sequence(PRBS9)
//               5: 11110000 pattern
//               6: 00001111 pattern
int appbt_bt_test_txpacket(unsigned char start_stop,
    unsigned char channel, unsigned char power, unsigned char modulation,
    unsigned char dh_type, unsigned char data_pattern, struct bt_addr addr);
// API: BR test mode -- recv packet
// start_stop: 0 - stop send; 1 - start send
// channel: BT channel. valid value 0-78
//          0: 2402 MHz
//          1: 2402 + 1 MHz
//          n: 2402 + n MHz
// packet_type: 0 - BR; 1/2/3 - Mbs
// data_pattern: 1: 0 pattern
//               2: 1 pattern
//               3: 1010 pattern
//               4: pseudorandom bit sequence(PRBS9)
//               5: 11110000 pattern
//               6: 00001111 pattern
int appbt_bt_test_rxpacket(unsigned char start_stop,
    unsigned char channel, unsigned char packet_type, unsigned char data_pattern,
    struct bt_addr addr);
// enter DTM mode
int appbt_le_dtm(int baudrate);
// query DTM mode
int appbt_le_is_dtm_mode(void);

int appbt_le_dtm_in_open(void);

// send a raw vendor HCI to controller
int appbt_vendor_rawhci(struct bt_task_vendor_cmd *cmd);

int appbt_temperature(int temperature);

void appbt_enable_hcidump(char enable);

void appbt_gpio_init(void);
BOOL appbt_chip_is_5803(void);
struct bt_task_command *alloc_bttask_command(int command_id, int payload_length);

struct bt_task_event * alloc_bt_event(unsigned short int event_type,
                                                  unsigned short int event_id,
                                                  int size);
// eat this message, skip upper layer process
void appbt_eat_message(struct bt_task_event * msg);

// API: user can inquiry bluetooth status through this API
int appbt_get_open_status(void);

struct bt_device_record *bt_find_device_record(struct bt_addr addr);

int send_bttask_command(struct bt_task_command * command);

void bt_update_device_record(void);

void *bt_malloc(unsigned size);

void bt_free(void *p);

unsigned char GetBTPmLock(void);

void SetBTPmLock(unsigned char lock);

void ClearBTPmLock(unsigned char lock);

int h5_is_busy(void);

void set_h5_busy(void);

void wakeup_bt_chip(void);

void enable_bt_chip_sleep(void);

BOOL host_wakeup_bt_low(void);

BOOL bt_wakeup_host_low(void);

UINT8 GetWifiConfigFlag(void);

UINT32 appbt_get_uart_id(void);

void appbt_clearup(void);

void asrbt_clearup(void);

void BTUARTDMARxEnable(uint32 port_id);

BOOL bt_get_chip_id(unsigned int *id);

void bt_set_firmware_location(int location);

void app_bt_dump_data(char* desc, uint8_t* data, uint16_t size);

void ble_find_device_record(unsigned char *peer_irk);

int bt_uart_rx_int_handle(unsigned int interruptInfo);

void bt_uart_dma_irq_preprocess(uint32 DINT);

UINT32 diag_get_32k_tick(void);

void EdgeDetectWakeupRegister(UINT32 MFPR_addr);

void bt_base_timer(unsigned int id);

int asr_bt_prepare_init(struct bt_user_cfg *bt_setting);

int copy_data_to_bt(char *src, uint32 len);

int appbt_set_check_controller_alive(unsigned char set_enable);

#ifdef __cplusplus
}
#endif // __cplusplus


/* BT internal used */
#define BTTASK_FLAG_UART_RX             (1 << 0)
#define BTTASK_FLAG_INTERNEL_MSG        (1 << 1)
#define BTTASK_FLAG_USER_MSG            (1 << 2)
#define BTTASK_FLAG_SHUTDOWN_REQUEST    (1 << 3) // user shutdown through this
#define BTTASK_FLAG_SHUTDOWN_COMPLETE   (1 << 4) // statck internal use
#define BTTASK_FLAG_BT_WAKEUP           (1 << 5) // statck internal use
#define BTTASK_FLAG_BT_H5_ACTIVE        (1 << 6) // statck internal use
#define BTTASK_FLAG_SET_ADDR_COMPLETE   (1 << 7) // statck internal use
#define BTTASK_FLAG_INTERNAL_TIMER      (1 << 8) // statck internal use
#define BTTASK_FLAG_ALL                 0xffffffff

#if 0
#define BTLog(fmt,args...)                                                    \
{                                                                                       \
    if (log_config.log_cfg != LOG_DISABLE)      \
    {                                                                                   \
        UARTLogPrintf_Extend(LOG_MODULE_BT, fmt, ##args);                              \
    }                                                                                   \
}

#define appbt_debug(fmt, args...) BTLog("[BTAPP]"fmt, ##args)
#define appbt_log(fmt, args...) BTLog("[BTLOG]"fmt, ##args)
#define appbt_uart_log(fmt, args...) BTLog("[BTUART]"fmt, ##args)
#define a2dp_debug(fmt, args...) BTLog("[BTA2DP]"fmt, ##args)
#define app_bt_dbg(fmt, args...) BTLog("[BT]"fmt"\r\n", ##args)
#endif

#endif

